import {PluginCommand} from "./PluginCommand";
import {ElementType, GeomType} from "../modeling/TypeDefine";
import {Direction, Point, ScriptVariableType} from "../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";
import {Vector3} from "three";

//约束类型
const CONSTRAINTTYPE = {
  Fix:0,  //固定
  Dis:1,  //尺寸
  Line:2, //共线
  PointOnCurve:3  //点在线上
}
class InsulationCoverFrameToolCommand extends PluginCommand {
  constructor() {
    super();
    this.params = null;
    this.innerDir = new THREE.Vector3(1,0,0);
  }

  async executeConfirm(params) {
    //删除原有数据
    await this.deleteData();

    this.params = params;
    //将当前航向变为数学航向
    this.params.dirCourse = this.getDirectionCourse(this.params.courseNo);

    //拷贝曲面
    let copySurface = await this.copySurface(this.params);
    if(!copySurface){
      return;
    }

    //获取所有合适的长桁站位（包含加强框长桁站位），并进行长桁站位排序
    let allStringerPlane = await this.queueStringerPlane(this.params);
    if(!allStringerPlane){
      return;
    }
    this.params.allQueueStringerPlane = allStringerPlane;

    //计算加强长桁在所有长桁站位面中的序号
    if(this.params.bReinforceFrame && this.params.reinforcedStringers.length > 0){
      this.calculateReinforceFramePos();
    }


    //通过航向编号获取航向向量
    let dirCourse = this.getDirCourse(this.params.courseNo);

    let lastSweepStringerPlane = allStringerPlane[allStringerPlane.length - 1];
    if(this.params.bReinforceFrame && this.params.reinforcedStringers.length > 0){
      //TODO暂时平台放样曲面支持的不好，加强框不进行绘制
      //lastSweepStringerPlane = this.params.reinforcedStringers[0];
    }

    //使用长桁站位截取曲面
    let trimSurfaceSweep = await this.trimSurface(copySurface,allStringerPlane[0],lastSweepStringerPlane);
    await this.event.clearPreview();
    if(!trimSurfaceSweep){
      return;
    }

    //对于当前框和蒙皮进行相交的线
    let sweepCurve = await this.getIntersectCurve(this.params.frames[0],trimSurfaceSweep);
    if(!sweepCurve){
      return;
    }

    //隐藏曲面
    let featureId = this.getFeatureId(trimSurfaceSweep);
    let entitiesRes = await this.toolQuery.getEntitiesByFeatureId(featureId);
    if (entitiesRes && entitiesRes?.data?.entities?.length > 0) {
      let entityId = entitiesRes?.data?.entities[0].id;
      await this.command.common.setEntityVisibleIncrement({entityIds:[entityId], status: 0});
    }

    //通过线与航向及长桁站位面来创建扫掠草图内容
    let sweepSolid = await this.createFrameModelSweep(this.params,dirCourse,sweepCurve,allStringerPlane[0],lastSweepStringerPlane);

    //加强框三维通过放样生成
    if(false && this.params.bReinforceFrame  && this.params.reinforcedStringers.length > 0){
      //使用长桁站位截取曲面
      let trimSurfaceLoft = await this.trimSurface(copySurface,lastSweepStringerPlane,allStringerPlane[allStringerPlane.length - 1]);
      await this.event.clearPreview();
      if(!trimSurfaceLoft){
        return;
      }

      //对于当前框和蒙皮进行相交的线
      let loftCurve = await this.getIntersectCurve(this.params.frames[0],trimSurfaceLoft);
      if(!loftCurve){
        return;
      }

      let loftSolid = await this.createFrameModelLoft(this.params,dirCourse,loftCurve,lastSweepStringerPlane,allStringerPlane[allStringerPlane.length - 1]);
    }

    //包框进行二维映射
    if(this.params.bReinforceFrame  && this.params.reinforcedStringers.length > 0){
      await this.drawCoverFrameSketchS(this.params,copySurface);
    }else{
      await this.drawCoverFrameSketch(this.params,trimSurfaceSweep);
    }
  }
  //删除数据
  async deleteData() {
    let res = await this.query.getFeaturesByNames(["复制曲面"]);
    if (res.data?.features.length > 0) {
      let copyFeature = res.data?.features[0];
      if (!copyFeature) {
        return;
      }
      let result = await this.toolQuery.getAllFeatures();
      let deleteFeatureIds = [];
      if (result?.data && result?.data.length > 0) {
        result?.data.forEach(feature => {
          if (feature.id >= copyFeature.id) {
            deleteFeatureIds.push(feature.id);
          }
        })
      }
      if (deleteFeatureIds.length > 0) {
        await this.command.common.deleteFeatureIncrement({featureIds: deleteFeatureIds});
      }
    }
  }
  //绘制包框二维制作草图
  async drawCoverFrameSketch(params,surface){
    //计算纵向即长桁间距
    await this.calculateParametersValue(params, surface);
    if(params.stringerDisList.length < 2){
      return;
    }
    //轴线、定位线相对于宽度的比例
    let extendRatio = 1.2;
    //草图中进行缩放的经验系数
    let zoomRatio = params.zoomRatio;

    //当前框站位在二维草图中的x值
    let frameX = 0;

    //框缘宽度
    let dFrameEdgeWidth = Math.abs(params.frameEdgeWidth);
    if(params.bFrameEdgeSymmetry){
      dFrameEdgeWidth = 2 * Math.abs(params.frameEdgeWidth);
    }

    //计算横向间距即隔热隔声层宽度dCWf = 2dM + 2(dFH - RIS) + dFW + k
    let dCoreWidth = 2 * params.dM + 2 * (params.standardFrameHeight - params.RIS) + dFrameEdgeWidth + params.k;
    //横向翻边宽度
    let dFlangeWidth = params.horizontalWidth;

    //竖向间距即芯体高度
    let dCoreHeight = params.stringerDisList[params.stringerDisList.length - 1] - params.stringerDisList[0];
    //竖向翻边宽度
    let dFlangeHeight = params.verticalWidth;

    //对应的值添加系数
    dCoreWidth *= zoomRatio;
    dCoreHeight *= zoomRatio;

    //根据对应的参数创建二维图及内部元素
    //在框站位上生成草图
    let sketch = this.command.sketch;
    await sketch.createSketchIncrement({sketchName: '',datumId: params.frames[0].id});

    //芯体四点
    let point2DLU = new Point(this.dealValue(-dCoreWidth / 2),this.dealValue(dCoreHeight / 2));
    let point2DLD = new Point(this.dealValue(-dCoreWidth / 2),this.dealValue(-dCoreHeight / 2));
    let point2DRU = new Point(this.dealValue(dCoreWidth / 2),this.dealValue(dCoreHeight / 2));
    let point2DRD = new Point(this.dealValue(dCoreWidth / 2),this.dealValue(-dCoreHeight / 2));

    //芯体四边
    let line2DL = await this.createSketchLine({startPoint: point2DLU,endPoint: point2DLD});
    let line2DD = await this.createSketchLine({startPoint: point2DLD,endPoint: point2DRD});
    let line2DR = await this.createSketchLine({startPoint: point2DRD,endPoint: point2DRU});
    let line2DU = await this.createSketchLine({startPoint: point2DRU,endPoint: point2DLU});

    await this.addConstraint(CONSTRAINTTYPE.Fix,{id:line2DD.id});
    await this.addConstraint(CONSTRAINTTYPE.Fix,{id:line2DL.id});

    //长桁方向的线进行约束
    //TODO 共线约束错误，暂时使用固定约束代替
    //await this.addConstraint(CONSTRAINTTYPE.Line,{firstId:line2DD.id,secondId:stringerRefLineList[0].id});
    //await this.addConstraint(CONSTRAINTTYPE.Line,{firstId:line2DU.id,secondId:stringerRefLineList[stringerRefLineList.length - 1].id});
    await this.addConstraint(CONSTRAINTTYPE.Fix,{id:line2DU.id});

    //绘制所有长桁的线
    let stringerRefLineList = [];
    //生成线的左侧点，用于创建约束时的尺寸标注位置
    let stringerRefPointPosL = [];
    let stringerRefPointPosR = [];
    for(let stringerIndex = 0;stringerIndex < params.stringerDisList.length;stringerIndex++){
      let dis = params.stringerDisList[stringerIndex] * zoomRatio;
      let stringerPointL = new Point(point2DLD.x - extendRatio * dCoreWidth / 2,point2DLD.y + dis);
      let stringerPointR = new Point(point2DRD.x + extendRatio * dCoreWidth / 2,point2DRD.y + dis);
      let refLine = await this.createReferenceLine({startPoint: stringerPointL,endPoint: stringerPointR});

      stringerRefLineList.push(refLine);
      stringerRefPointPosL.push(stringerPointL);
      stringerRefPointPosR.push(stringerPointR);

      //创建约束
      if(stringerIndex === 0){
        //第一个采用固定约束
        await this.addConstraint(CONSTRAINTTYPE.Fix,{id:refLine.id});
      }else{
        //创建与上一个之间的距离约束
        let lastId = stringerRefLineList[stringerIndex - 1].id;

        let lastRefPointPos = stringerRefPointPosL[stringerIndex - 1];
        let centerPointPos = new Point((stringerPointL.x + lastRefPointPos.x) * 0.5 ,(stringerPointL.y + lastRefPointPos.y) * 0.5);
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:refLine.id,secondId:lastId,x:centerPointPos.x,y:centerPointPos.y});
      }
    }


    //框方向的线进行约束
    await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DL.id,secondId:line2DR.id,x:(point2DLD.x + point2DRD.x) * 0.5,y:point2DLD.y});

    //翻边
    if(true){
      //翻边四点
      let point2DLUF = new Point(this.dealValue(-dCoreWidth / 2 - dFlangeWidth),this.dealValue(dCoreHeight / 2 + dFlangeHeight));
      let point2DLDF = new Point(this.dealValue(-dCoreWidth / 2 - dFlangeWidth),this.dealValue(-dCoreHeight / 2 - dFlangeHeight));
      let point2DRUF = new Point(this.dealValue(dCoreWidth / 2 + dFlangeWidth),this.dealValue(dCoreHeight / 2 + dFlangeHeight));
      let point2DRDF = new Point(this.dealValue(dCoreWidth / 2 + dFlangeWidth),this.dealValue(-dCoreHeight / 2 - dFlangeHeight));

      //翻边四边
      let line2DLF = await this.createSketchLine({startPoint: point2DLUF,endPoint: point2DLDF});
      let line2DDF = await this.createSketchLine({startPoint: point2DLDF,endPoint: point2DRDF});
      let line2DRF = await this.createSketchLine({startPoint: point2DRDF,endPoint: point2DRUF});
      let line2DUF = await this.createSketchLine({startPoint: point2DRUF,endPoint: point2DLUF});

      //长桁方向
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DD.id,secondId:line2DDF.id,x:point2DLD.x,y:(point2DLD.y + point2DLDF.y) * 0.5});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DU.id,secondId:line2DUF.id,x:point2DLU.x,y:(point2DLU.y + point2DLUF.y) * 0.5});
      //框方向
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DL.id,secondId:line2DLF.id,x:(point2DLD.x + point2DLDF.x) * 0.5,y:point2DLD.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DR.id,secondId:line2DRF.id,x:(point2DRD.x + point2DRDF.x) * 0.5,y:point2DRD.y});
    }

    //开孔计算
    if(true && params.installHoleInfoList.length > 0){
      //计算开孔参数
      //孔轴线偏移值
      let holeOffsetValue = params.holeAxisOffset;
      let pointHole2DLU = new Point(this.dealValue(point2DLU.x + holeOffsetValue),this.dealValue(point2DLU.y + extendRatio * dCoreHeight / 2));
      let pointHole2DLD = new Point(this.dealValue(point2DLD.x + holeOffsetValue),this.dealValue(point2DLD.y - extendRatio * dCoreHeight / 2));
      let pointHole2DRU = new Point(this.dealValue(point2DRU.x - holeOffsetValue),this.dealValue(point2DRU.y + extendRatio * dCoreHeight / 2));
      let pointHole2DRD = new Point(this.dealValue(point2DRD.x - holeOffsetValue),this.dealValue(point2DRD.y - extendRatio * dCoreHeight / 2));

      //创建空心孔轴线
      let line2DHoleAxisL = await this.createReferenceLine({startPoint: pointHole2DLU,endPoint: pointHole2DLD});
      let line2DHoleAxisR = await this.createReferenceLine({startPoint: pointHole2DRU,endPoint: pointHole2DRD});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DL.id,secondId:line2DHoleAxisL.id,x:(point2DLD.x + pointHole2DLD.x) * 0.5,y:point2DLD.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DR.id,secondId:line2DHoleAxisR.id,x:(point2DRD.x + pointHole2DRD.x) * 0.5,y:point2DRD.y});

      for(let pointIndex = 0;pointIndex < params.installHoleInfoList.length;pointIndex++){
        let curHoleInfo = params.installHoleInfoList[pointIndex];

        let hole = curHoleInfo.installHolePoint;
        let position = hole.params.position;
        let holePoint = new THREE.Vector3(position.x,position.y,position.z);
        //当前点计算出距离最近的长桁站位面，有正负值之分，正值为长桁前进方向，负值为长桁前进负向
        let holeLocateData = this.getMinDisPlane(holePoint,params.allQueueStringerPlane);
        let yValue = point2DLD.y + (params.stringerDisList[holeLocateData.minNo] + holeLocateData.dis) * zoomRatio;
        if(curHoleInfo.holeSymmetry != 2){
          //创建开孔点
          let point = await this.createPoint({x:pointHole2DLU.x,y:yValue});
          //创建开孔样式
          await this.createHole(new THREE.Vector3(pointHole2DLU.x,yValue),curHoleInfo.holeType);

          let minDisStringerId = stringerRefLineList[holeLocateData.minNo].id;
          //创建开孔约束
          await this.addConstraint(CONSTRAINTTYPE.PointOnCurve,{firstId:point.id,secondId:line2DHoleAxisL.id});
          await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:point.id,secondId:minDisStringerId,x:pointHole2DLU.x,y:(yValue + stringerRefPointPosL[holeLocateData.minNo].y) * 0.5});
        }
        if(curHoleInfo.holeSymmetry != 1){
          //创建开孔点
          let point = await this.createPoint({x:pointHole2DRU.x,y:yValue});

          //创建开孔样式
          await this.createHole(new THREE.Vector3(pointHole2DRU.x,yValue),curHoleInfo.holeType);

          let minDisStringerId = stringerRefLineList[holeLocateData.minNo].id;
          //创建开孔约束
          await this.addConstraint(CONSTRAINTTYPE.PointOnCurve,{firstId:point.id,secondId:line2DHoleAxisR.id});
          await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:point.id,secondId:minDisStringerId,x:pointHole2DRU.x,y:(yValue + stringerRefPointPosR[holeLocateData.minNo].y) * 0.5});
        }
      }
    }
    //开叉
    if(true){
      //创建开叉特征
      //TODO 开叉特征现行无指导方案，按照理解进行技术解析，共有两种开叉方式
      //具有上方开叉和侧方开叉两种情形
      for(let forkIndex = 0;forkIndex < params.forkLineList.length;forkIndex++){
        let forkLine = params.forkLineList[forkIndex];
        //获取当前开叉线的端点和开叉方式
        let forkTempS = forkLine.params.startPoint;
        let forkTempE = forkLine.params.endPoint;
        let forkPointS = new THREE.Vector3(forkTempS[0],forkTempS[1],forkTempS[2]);
        let forkPointE = new THREE.Vector3(forkTempE[0],forkTempE[1],forkTempE[2]);

        let point2DS = new THREE.Vector3();
        let point2DE = new THREE.Vector3();

        //进行起点终点约束的线ID
        let constraintIdXS = line2DL.id;
        let constraintIdXE = line2DL.id;
        let constraintXValueS = point2DLD.x;
        let constraintXValueE = point2DLD.x;
        //开叉方向，分为侧开叉和上开叉，上开叉为1，侧开叉为2
        let forkDir = params.forkType;
        if(forkDir === 1){
          //开叉方向向上，计算开叉点到框站位的距离，来确定二维草图中到中心轴线的距离
          let forkFrameDisDataS = this.getMinDisPlane(forkPointS,params.frames);
          let forkFrameDisDataE = this.getMinDisPlane(forkPointE,params.frames);
          point2DS.x = frameX + forkFrameDisDataS.dis * zoomRatio;
          point2DE.x = frameX + forkFrameDisDataE.dis * zoomRatio;

          //距离左右侧哪个近记录哪个
          if(forkFrameDisDataS.dis > 0){
            constraintIdXS = line2DR.id;
            constraintXValueS = point2DRD.x;
          }
          if(forkFrameDisDataE.dis > 0){
            constraintIdXE = line2DR.id;
            constraintXValueE = point2DRD.x;
          }
        }else if(forkDir === 2){
          //判断在左侧还是右侧，使用中点来进行判断，在框站位左侧为左侧开叉，在框站位右侧为右侧开叉
          let forkCenterPointData = this.getMinDisPlane((forkPointS.clone().add(forkPointE)).multiplyScalar(0.5),params.frames);

          let pointIdS = await this.createPointByCurve(forkLine,0);
          let pointIdE = await this.createPointByCurve(forkLine,100);
          let disS = await this.measureDis(pointIdS,this.params.skins[0].id);
          let disE = await this.measureDis(pointIdE,this.params.skins[0].id);

          disS -= params.stringerHeight;
          disE -= params.stringerHeight;

          if(forkCenterPointData.dis > 0){
            point2DS.x = point2DRU.x - disS;
            point2DE.x = point2DRU.x - disE;

            //约束线为右侧线
            constraintIdXS = line2DR.id;
            constraintIdXE = line2DR.id;
            constraintXValueS = point2DRD.x;
            constraintXValueE = point2DRD.x;
          }else{
            point2DS.x = point2DLU.x + disS;
            point2DE.x = point2DLU.x + disE;

            //约束线为左侧线
            constraintIdXS = line2DL.id;
            constraintIdXE = line2DL.id;
            constraintXValueS = point2DLD.x;
            constraintXValueE = point2DLD.x;
          }
        }
        //V向到长桁站位面计算
        let forkStringerDisDataS = this.getMinDisPlane(forkPointS,params.allQueueStringerPlane);
        let forkStringerDisDataE = this.getMinDisPlane(forkPointE,params.allQueueStringerPlane);
        point2DS.y = point2DRD.y + (params.stringerDisList[forkStringerDisDataS.minNo] + forkStringerDisDataS.dis) * zoomRatio;
        point2DE.y = point2DRD.y + (params.stringerDisList[forkStringerDisDataE.minNo] + forkStringerDisDataE.dis) * zoomRatio;

        //y向即长桁方向上的最近距离
        let constraintIdYS = stringerRefLineList[forkStringerDisDataS.minNo].id;
        let constraintIdYE = stringerRefLineList[forkStringerDisDataE.minNo].id;

        //创建线的端点
        let pointS = await this.createPoint({x:point2DS.x,y:point2DS.y});
        let pointE = await this.createPoint({x:point2DE.x,y:point2DE.y});

        await sketch.createSketchLineIncrement({startPoint: new Point(point2DS.x,point2DS.y),endPoint: new Point(point2DE.x,point2DE.y)});

        //创建约束
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointS.id,secondId:constraintIdXS,x:(constraintXValueS + point2DS.x) * 0.5,y:point2DS.y});     //起点X向
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointS.id,secondId:constraintIdYS,x:point2DS.x,y:(stringerRefPointPosL[forkStringerDisDataS.minNo].y + point2DS.y) * 0.5});     //起点Y向
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointE.id,secondId:constraintIdXE,x:(constraintXValueE + point2DE.x) * 0.5,y:point2DE.y});     //终点X向
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointE.id,secondId:constraintIdYE,x:point2DE.x,y:(stringerRefPointPosL[forkStringerDisDataE.minNo].y + point2DE.y) * 0.5});     //终点Y向

        //根据起点和终点绘制开叉二维线
        await this.createForkLine(point2DS,point2DE,params.centerLineDistance);
      }
    }
    //绘制航向以及航向文字
    if(true){
      //根据当前的芯体大小来确定字体大小以及箭头大小
      //宽度与二维绘制宽度一致
      let arrowLengthRatio = 0.5;
      let arrowDisRatio = 0.4;
      let arrowSize = 0.05;
      let pointCourseS = new THREE.Vector3(point2DLD.x + arrowLengthRatio * dCoreWidth * 0.5,point2DLD.y - arrowDisRatio * dCoreHeight);
      let pointCourseE = new THREE.Vector3(point2DRD.x - arrowLengthRatio * dCoreWidth * 0.5,point2DLD.y - arrowDisRatio * dCoreHeight);
      let pointArrow1 = new THREE.Vector3(pointCourseE.x - dCoreWidth * arrowLengthRatio * arrowSize,pointCourseE.y + dCoreWidth * arrowLengthRatio  * arrowSize* 0.5);
      let pointArrow2 = new THREE.Vector3(pointCourseE.x - dCoreWidth * arrowLengthRatio * arrowSize,pointCourseE.y - dCoreWidth * arrowLengthRatio  * arrowSize* 0.5);

      await sketch.createSketchLineIncrement({startPoint: new Point(pointCourseS.x,pointCourseS.y),endPoint: new Point(pointCourseE.x,pointCourseE.y)});
      await sketch.createSketchLineIncrement({startPoint: new Point(pointArrow1.x,pointArrow1.y),endPoint: new Point(pointCourseE.x,pointCourseE.y)});
      await sketch.createSketchLineIncrement({startPoint: new Point(pointArrow2.x,pointArrow2.y),endPoint: new Point(pointCourseE.x,pointCourseE.y)});

    }

    //计算面积和平均宽度
    let dH = dCoreHeight;
    let dW = dCoreWidth;
    await this.addVariable("W1",dW);
    await this.addVariable("L3",dH);

    await this.command.sketch.exitSketchIncrement();
  }
  //绘制包框二维制作草图
  async drawCoverFrameSketchS(params,surface){
    //计算纵向即长桁间距
    await this.calculateParametersValue(params, surface);
    if(params.stringerDisList.length < 2){
      return;
    }
    //轴线、定位线相对于宽度的比例
    let extendRatio = 1.2;
    //草图中进行缩放的经验系数
    let zoomRatio = params.zoomRatio;

    //当前框站位在二维草图中的x值
    let frameX = 0;

    //框缘宽度
    let dFrameEdgeWidth = Math.abs(params.frameEdgeWidth);
    if(params.bFrameEdgeSymmetry){
      dFrameEdgeWidth = 2 * Math.abs(params.frameEdgeWidth);
    }

    //计算横向间距即隔热隔声层宽度dCWf = 2dM + 2(dFH - RIS) + dFW + k
    let dCoreWidth = 2 * params.dM + 2 * (params.standardFrameHeight - params.RIS) + dFrameEdgeWidth + params.k;
    //横向翻边宽度
    let dFlangeWidth = params.verticalWidth;

    //竖向间距即芯体高度
    let dCoreHeight = params.stringerDisList[params.stringerDisList.length - 1] - params.stringerDisList[0];
    //竖向翻边宽度
    let dFlangeHeight = params.horizontalWidth;

    //对应的值添加系数
    dCoreWidth *= zoomRatio;
    dCoreHeight *= zoomRatio;

    //加强框缘宽度
    let dFrameEdgeWidthS = Math.abs(params.frameEdgeWidth);
    if(params.bFrameEdgeSymmetry){
      dFrameEdgeWidthS = 2 * Math.abs(params.frameEdgeWidth);
    }
    let dCoreWidthS = 2 * params.dM + 2 * (params.standardFrameHeightS - params.RIS) + dFrameEdgeWidthS + params.k;
    dCoreWidthS *= zoomRatio;

    //加强芯体宽度比例
    let dSRatio = dCoreWidthS / dCoreWidth;

    //根据对应的参数创建二维图及内部元素
    //在框站位上生成草图
    let sketch = this.command.sketch;
    await sketch.createSketchIncrement({sketchName: '',datumId: params.frames[0].id});

    //绘制二维芯体的最下、最左、最右、最上值
    let valueDY = -dCoreHeight * 0.5;
    let valueLX = -dCoreWidthS * 0.5;
    let valueUY = dCoreHeight * 0.5;
    let valueRX = dCoreWidthS * 0.5;

    //绘制所有长桁的线
    let stringerRefLineList = [];
    //生成线的左侧点，用于创建约束时的尺寸标注位置
    let stringerRefPointPosL = [];
    let stringerRefPointPosR = [];
    for(let stringerIndex = 0;stringerIndex < params.stringerDisList.length;stringerIndex++){
      let dis = params.stringerDisList[stringerIndex] * zoomRatio;
      let stringerPointL = new Point(valueLX - extendRatio * dCoreWidthS / 2,valueDY + dis);
      let stringerPointR = new Point(valueRX + extendRatio * dCoreWidthS / 2,valueDY + dis);
      let refLine = await this.createReferenceLine({startPoint: stringerPointL,endPoint: stringerPointR});
      stringerRefLineList.push(refLine);
      stringerRefPointPosL.push(stringerPointL);
      stringerRefPointPosR.push(stringerPointR);

      //创建约束
      if(stringerIndex === 0){
        //第一个采用固定约束
        await this.addConstraint(CONSTRAINTTYPE.Fix,{id:refLine.id});
      }else{
        //创建与上一个之间的距离约束
        let lastId = stringerRefLineList[stringerIndex - 1].id;

        let lastRefPointPos = stringerRefPointPosL[stringerIndex - 1];
        let centerPointPos = new Point((stringerPointL.x + lastRefPointPos.x) * 0.5 ,(stringerPointL.y + lastRefPointPos.y) * 0.5);
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:refLine.id,secondId:lastId,x:centerPointPos.x,y:centerPointPos.y});
      }
    }

    //加强长桁所在距离
    let dCoreHeightS = this.params.stringerDisList[this.params.nNoS] * zoomRatio;

    //芯体四点
    let point2DLU = new Point(this.dealValue(-dCoreWidth / 2),this.dealValue(-dCoreHeight / 2 + dCoreHeightS));
    let point2DLD = new Point(this.dealValue(-dCoreWidth / 2),this.dealValue(-dCoreHeight / 2));
    let point2DRU = new Point(this.dealValue(dCoreWidth / 2),this.dealValue(-dCoreHeight / 2 + dCoreHeightS));
    let point2DRD = new Point(this.dealValue(dCoreWidth / 2),this.dealValue(-dCoreHeight / 2));
    //加强两点
    let point2DLUS = new Point(this.dealValue(-dCoreWidthS / 2),this.dealValue(dCoreHeight / 2));
    let point2DRUS = new Point(this.dealValue(dCoreWidthS / 2),this.dealValue(dCoreHeight / 2));

    //芯体六边
    let line2DL = await this.createSketchLine({startPoint: point2DLU,endPoint: point2DLD});
    let line2DD = await this.createSketchLine({startPoint: point2DLD,endPoint: point2DRD});
    let line2DR = await this.createSketchLine({startPoint: point2DRD,endPoint: point2DRU});
    let line2DLS = await this.createSketchLine({startPoint: point2DLU,endPoint: point2DLUS});
    let line2DRS = await this.createSketchLine({startPoint: point2DRU,endPoint: point2DRUS});
    let line2DUS = await this.createSketchLine({startPoint: point2DRUS,endPoint: point2DLUS});

    //芯体线进行约束
    //左侧固定，下侧固定，右侧左侧距离
    await this.addConstraint(CONSTRAINTTYPE.Fix,{id:line2DD.id});
    await this.addConstraint(CONSTRAINTTYPE.Fix,{id:line2DL.id});
    await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DL.id,secondId:line2DR.id,x:(point2DLD.x + point2DRD.x) * 0.5,y:point2DLD.y});
    //左上点左侧距离，
    let createPoint2DLUS = await this.createPoint({x:point2DLUS.x,y:point2DLUS.y});
    await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:createPoint2DLUS.id,secondId:line2DL.id,x:(createPoint2DLUS.x + line2DL.x) * 0.5,y:createPoint2DLUS.y});
    //右上点右侧距离，
    let createPoint2DRUS = await this.createPoint({x:point2DRUS.x,y:point2DRUS.y});
    await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:createPoint2DRUS.id,secondId:line2DR.id,x:(createPoint2DRUS.x + line2DR.x) * 0.5,y:createPoint2DRUS.y});

    //翻边
    if(true){
      //求往外偏的点
      let pointList = [point2DRD,point2DRU,point2DRUS,point2DLUS,point2DLU,point2DLD];
      let offsetPointList = this.getOffsetPointList(pointList,params.horizontalWidth,params.verticalWidth);
      //翻边六点
      let point2DRDF = this.getNewPoint(offsetPointList[5]);
      let point2DRUF = this.getNewPoint(offsetPointList[0]);
      let point2DRUSF = this.getNewPoint(offsetPointList[1]);
      let point2DLUSF = this.getNewPoint(offsetPointList[2]);
      let point2DLUF = this.getNewPoint(offsetPointList[3]);
      let point2DLDF = this.getNewPoint(offsetPointList[4]);

      //翻边六边
      let line2DRF = await this.createSketchLine({startPoint: point2DRDF,endPoint: point2DRUF});
      let line2DRSF = await this.createSketchLine({startPoint: point2DRUF,endPoint: point2DRUSF});
      let line2DUSF = await this.createSketchLine({startPoint: point2DRUSF,endPoint: point2DLUSF});
      let line2DLSF = await this.createSketchLine({startPoint: point2DLUSF,endPoint: point2DLUF});
      let line2DLF = await this.createSketchLine({startPoint: point2DLUF,endPoint: point2DLDF});
      let line2DDF = await this.createSketchLine({startPoint: point2DLDF,endPoint: point2DRDF});

      //创建翻边约束
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DR.id,secondId:line2DRF.id,x:point2DRDF.x,y:point2DRDF.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DRS.id,secondId:line2DRSF.id,x:point2DRUF.x,y:point2DRUF.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DUS.id,secondId:line2DUSF.id,x:point2DRUSF.x,y:point2DRUSF.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DLS.id,secondId:line2DLSF.id,x:point2DLUSF.x,y:point2DLUSF.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DL.id,secondId:line2DLF.id,x:point2DLUF.x,y:point2DLUF.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DD.id,secondId:line2DDF.id,x:point2DLDF.x,y:point2DLDF.y});
    }

    //开孔计算
    if(true && params.installHoleInfoList.length > 0){
      //计算开孔参数
      //孔轴线偏移值
      let holeOffsetValue = params.holeAxisOffset;
      //需要沿普通框边和加强框边偏移一定距离进行计算位置
      let polyLineHoleCenterR = this.calculatePolyLine(this.getThreeVector3(point2DRUS),
        this.getThreeVector3(point2DRU),
        this.getThreeVector3(point2DRD),
        holeOffsetValue,
        extendRatio);
      let polyLineHoleCenterL = this.calculatePolyLine(this.getThreeVector3(point2DLD),
        this.getThreeVector3(point2DLU),
        this.getThreeVector3(point2DLUS),
        holeOffsetValue,
        extendRatio);

      let lineHoleAxis2DL = await this.createReferenceLine({startPoint: this.getNewPoint(polyLineHoleCenterL.point1),endPoint: this.getNewPoint(polyLineHoleCenterL.point2)});
      let lineHoleAxis2DLS = await this.createReferenceLine({startPoint: this.getNewPoint(polyLineHoleCenterL.point2),endPoint: this.getNewPoint(polyLineHoleCenterL.point3)});
      let lineHoleAxis2DRS = await this.createReferenceLine({startPoint: this.getNewPoint(polyLineHoleCenterR.point1),endPoint: this.getNewPoint(polyLineHoleCenterR.point2)});
      let lineHoleAxis2DR = await this.createReferenceLine({startPoint: this.getNewPoint(polyLineHoleCenterR.point2),endPoint: this.getNewPoint(polyLineHoleCenterR.point3)});
      let holeCenterPoint1L = polyLineHoleCenterL.point1;
      let holeCenterPoint2L = polyLineHoleCenterL.point2;
      let holeCenterPoint3L = polyLineHoleCenterL.point3;
      let holeCenterPoint3R = polyLineHoleCenterR.point3;
      let holeCenterPoint2R = polyLineHoleCenterR.point2;
      let holeCenterPoint1R = polyLineHoleCenterR.point1;

      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DL.id,secondId:lineHoleAxis2DL.id,x:point2DLD.x,y:point2DLD.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DLS.id,secondId:lineHoleAxis2DLS.id,x:point2DLUS.x,y:point2DLUS.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DRS.id,secondId:lineHoleAxis2DRS.id,x:point2DRUS.x,y:point2DRUS.y});
      await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:line2DR.id,secondId:lineHoleAxis2DR.id,x:point2DRD.x,y:point2DRD.y});

      for(let pointIndex = 0;pointIndex < params.installHoleInfoList.length;pointIndex++) {
        let curHoleInfo = params.installHoleInfoList[pointIndex];
        let hole = curHoleInfo.installHolePoint;

        let position = hole.params.position;
        let holePoint = new THREE.Vector3(position.x,position.y,position.z);
        let holeLocateData = this.getMinDisPlane(holePoint,params.allQueueStringerPlane);
        if(curHoleInfo.holeSymmetry != 2){
          //计算孔中心位置
          let pointHoleCenter = new THREE.Vector3();
          pointHoleCenter.y = point2DLD.y + (params.stringerDisList[holeLocateData.minNo] + holeLocateData.dis) * zoomRatio;
          let lineHoleCenterRefL = lineHoleAxis2DL;
          //通过点的y值计算点的x值
          if(pointHoleCenter.y < holeCenterPoint2L.y){
            pointHoleCenter.x = holeCenterPoint2L.x;
          }else{
            pointHoleCenter.x = holeCenterPoint2L.x + ((holeCenterPoint3L.x - holeCenterPoint2L.x)/(holeCenterPoint3L.y - holeCenterPoint2L.y))*(pointHoleCenter.y - holeCenterPoint2L.y);
            lineHoleCenterRefL = lineHoleAxis2DLS;
          }

          //创建开孔点
          let createPointHoleL = await this.createPoint({x:pointHoleCenter.x,y:pointHoleCenter.y});

          //创建开孔样式
          await this.createHole(pointHoleCenter,curHoleInfo.holeType);

          let minDisStringerId = stringerRefLineList[holeLocateData.minNo].id;
          //创建开孔约束
          await this.addConstraint(CONSTRAINTTYPE.PointOnCurve,{firstId:createPointHoleL.id,secondId:lineHoleCenterRefL.id});
          await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:createPointHoleL.id,secondId:minDisStringerId,x:pointHoleCenter.x,y:pointHoleCenter.y});
        }
        if(curHoleInfo.holeSymmetry != 1){
          //计算孔中心位置
          let pointHoleCenter = new THREE.Vector3();
          pointHoleCenter.y = point2DRD.y + (params.stringerDisList[holeLocateData.minNo] + holeLocateData.dis) * zoomRatio;
          let lineHoleCenterRefR = lineHoleAxis2DR;
          //通过点的y值计算点的x值
          if(pointHoleCenter.y < holeCenterPoint2R.y){
            pointHoleCenter.x = holeCenterPoint2R.x;
          }else{
            pointHoleCenter.x = holeCenterPoint2R.x + ((holeCenterPoint1R.x - holeCenterPoint2R.x)/(holeCenterPoint1R.y - holeCenterPoint2R.y))*(pointHoleCenter.y - holeCenterPoint2R.y);
            lineHoleCenterRefR = lineHoleAxis2DRS;
          }

          //创建开孔点
          let createPointHoleR = await this.createPoint({x:pointHoleCenter.x,y:pointHoleCenter.y});

          //创建开孔样式
          await this.createHole(pointHoleCenter,curHoleInfo.holeType);

          let minDisStringerId = stringerRefLineList[holeLocateData.minNo].id;
          //创建开孔约束
          await this.addConstraint(CONSTRAINTTYPE.PointOnCurve,{firstId:createPointHoleR.id,secondId:lineHoleCenterRefR.id});
          await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:createPointHoleR.id,secondId:minDisStringerId,x:pointHoleCenter.x,y:pointHoleCenter.y});
        }
      }
    }

    //开叉
    if(true){
      //创建开叉特征
      //TODO 开叉特征现行无指导方案，按照理解进行技术解析，共有两种开叉方式
      //具有上方开叉和侧方开叉两种情形
      for(let forkIndex = 0;forkIndex < params.forkLineList.length;forkIndex++){
        let forkLine = params.forkLineList[forkIndex];
        //获取当前开叉线的端点和开叉方式
        let forkTempS = forkLine.params.startPoint;
        let forkTempE = forkLine.params.endPoint;
        let forkPointS = new THREE.Vector3(forkTempS[0],forkTempS[1],forkTempS[2]);
        let forkPointE = new THREE.Vector3(forkTempE[0],forkTempE[1],forkTempE[2]);

        let point2DForkS = new THREE.Vector3();
        let point2DForkE = new THREE.Vector3();

        //进行起点终点约束的线ID
        let constraintIdXS = line2DL.id;
        let constraintIdXE = line2DL.id;
        let constraintXValueS = point2DLD.x;
        let constraintXValueE = point2DLD.x;


        //V向到长桁站位面计算
        let forkStringerDisDataS = this.getMinDisPlane(forkPointS,params.allQueueStringerPlane);
        let forkStringerDisDataE = this.getMinDisPlane(forkPointE,params.allQueueStringerPlane);
        point2DForkS.y = point2DRD.y + (params.stringerDisList[forkStringerDisDataS.minNo] + forkStringerDisDataS.dis) * zoomRatio;
        point2DForkE.y = point2DRD.y + (params.stringerDisList[forkStringerDisDataE.minNo] + forkStringerDisDataE.dis) * zoomRatio;

        //开叉方向，分为侧开叉和上开叉，上开叉为1，侧开叉为2
        let forkDir = params.forkType;
        if(forkDir === 1){
          //开叉方向向上，计算开叉点到框站位的距离，来确定二维草图中到中心轴线的距离
          let forkFrameDisDataS = this.getMinDisPlane(forkPointS,params.frames);
          let forkFrameDisDataE = this.getMinDisPlane(forkPointE,params.frames);
          point2DForkS.x = frameX + forkFrameDisDataS.dis * zoomRatio;
          point2DForkE.x = frameX + forkFrameDisDataE.dis * zoomRatio;

          //距离左右侧哪个近记录哪个
          if(forkFrameDisDataS.dis > 0){
            constraintIdXS = line2DR.id;
            constraintXValueS = point2DRD.x;
          }
          if(forkFrameDisDataE.dis > 0){
            constraintIdXE = line2DR.id;
            constraintXValueE = point2DRD.x;
          }
        }else if(forkDir === 2){
          //判断在左侧还是右侧，使用中点来进行判断，在框站位左侧为左侧开叉，在框站位右侧为右侧开叉
          let forkCenterPointData = this.getMinDisPlane((forkPointS.clone().add(forkPointE)).multiplyScalar(0.5),params.frames);

          let pointIdS = await this.createPointByCurve(forkLine,0);
          let pointIdE = await this.createPointByCurve(forkLine,100);
          let disS = await this.measureDis(pointIdS,this.params.skins[0].id);
          let disE = await this.measureDis(pointIdE,this.params.skins[0].id);
          disS -= params.stringerHeight;
          disE -= params.stringerHeight;

          //在加强长桁之后按照比例进行距离放大
          if(forkCenterPointData.dis > 0){
            //通过点的y值计算点的x值
            if(point2DForkS.y < point2DRU.y){
              point2DForkS.x = point2DRU.x - disS;
            }else{
              point2DForkS.x = -disS * dSRatio + point2DRU.x + (point2DRUS.x - point2DRU.x) / (point2DRUS.y - point2DRU.y) * (point2DForkS.y - point2DRU.y);
            }
            //通过点的y值计算点的x值
            if(point2DForkE.y < point2DRU.y){
              point2DForkE.x = point2DRU.x - disE;
            }else{
              point2DForkE.x = -disE * dSRatio + point2DRU.x + (point2DRUS.x - point2DRU.x) / (point2DRUS.y - point2DRU.y) * (point2DForkS.y - point2DRU.y);
            }

            //约束线为右侧线
            constraintIdXS = line2DR.id;
            constraintIdXE = line2DR.id;
            constraintXValueS = point2DRD.x;
            constraintXValueE = point2DRD.x;
          }else{

            //通过点的y值计算点的x值
            if(point2DForkS.y < point2DLU.y){
              point2DForkS.x = point2DLU.x + disS;
            }else{
              point2DForkS.x = disS * dSRatio + point2DLU.x + (point2DLUS.x - point2DLU.x) / (point2DLUS.y - point2DLU.y) * (point2DForkS.y - point2DLU.y);
            }
            //通过点的y值计算点的x值
            if(point2DForkE.y < point2DLU.y){
              point2DForkE.x = point2DLU.x + disE;
            }else{
              point2DForkE.x = disE * dSRatio + point2DLU.x + (point2DLUS.x - point2DLU.x) / (point2DLUS.y - point2DLU.y) * (point2DForkS.y - point2DLU.y);
            }
          }
        }

        //y向即长桁方向上的最近距离
        let constraintIdYS = stringerRefLineList[forkStringerDisDataS.minNo].id;
        let constraintIdYE = stringerRefLineList[forkStringerDisDataE.minNo].id;

        //创建线的端点
        let pointS = await this.createPoint({x:point2DForkS.x,y:point2DForkS.y});
        let pointE = await this.createPoint({x:point2DForkE.x,y:point2DForkE.y});

        await sketch.createSketchLineIncrement({startPoint: new Point(point2DForkS.x,point2DForkS.y),endPoint: new Point(point2DForkE.x,point2DForkE.y)});

        //创建约束
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointS.id,secondId:constraintIdXS,x:(constraintXValueS + point2DForkS.x) * 0.5,y:point2DForkS.y});     //起点X向
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointS.id,secondId:constraintIdYS,x:point2DForkS.x,y:(stringerRefPointPosL[forkStringerDisDataS.minNo].y + point2DForkS.y) * 0.5});     //起点Y向
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointE.id,secondId:constraintIdXE,x:(constraintXValueE + point2DForkE.x) * 0.5,y:point2DForkE.y});     //终点X向
        await this.addConstraint(CONSTRAINTTYPE.Dis,{firstId:pointE.id,secondId:constraintIdYE,x:point2DForkE.x,y:(stringerRefPointPosL[forkStringerDisDataE.minNo].y + point2DForkE.y) * 0.5});     //终点Y向

        //根据起点和终点绘制开叉二维线
        await this.createForkLine(point2DForkS,point2DForkE,params.centerLineDistance);
      }
    }

    //绘制航向以及航向文字
    if(true){
      //根据当前的芯体大小来确定字体大小以及箭头大小
      //宽度与二维绘制宽度一致
      let arrowLengthRatio = 0.5;
      let arrowDisRatio = 0.4;
      let arrowSize = 0.05;
      let pointCourseS = new THREE.Vector3(point2DLD.x + arrowLengthRatio * dCoreWidth * 0.5,point2DLD.y - arrowDisRatio * dCoreHeight);
      let pointCourseE = new THREE.Vector3(point2DRD.x - arrowLengthRatio * dCoreWidth * 0.5,point2DLD.y - arrowDisRatio * dCoreHeight);
      let pointArrow1 = new THREE.Vector3(pointCourseE.x - dCoreWidth * arrowLengthRatio * arrowSize,pointCourseE.y + dCoreWidth * arrowLengthRatio  * arrowSize* 0.5);
      let pointArrow2 = new THREE.Vector3(pointCourseE.x - dCoreWidth * arrowLengthRatio * arrowSize,pointCourseE.y - dCoreWidth * arrowLengthRatio  * arrowSize* 0.5);

      await sketch.createSketchLineIncrement({startPoint: new Point(pointCourseS.x,pointCourseS.y),endPoint: new Point(pointCourseE.x,pointCourseE.y)});
      await sketch.createSketchLineIncrement({startPoint: new Point(pointArrow1.x,pointArrow1.y),endPoint: new Point(pointCourseE.x,pointCourseE.y)});
      await sketch.createSketchLineIncrement({startPoint: new Point(pointArrow2.x,pointArrow2.y),endPoint: new Point(pointCourseE.x,pointCourseE.y)});
    }


    //计算面积和平均宽度
    let dH = dCoreHeight;
    let dW1 = dCoreWidth;
    let dW2 = point2DRUS.x - point2DLUS.x;
    let dHSameW = point2DLU.y - point2DLD.y;    //等宽高度
    let dHNoSameW = dCoreHeight - dHSameW;      //不等宽高度
    let dS = dHSameW * dW1 + (dW1 + dW2) / 2 * dHNoSameW;
    let dW = dS / dH;

    await this.addVariable("W1",dW);
    await this.addVariable("L3",dH);

    await this.command.sketch.exitSketchIncrement();
  }
  async createHole(point2D, holeType) {
    let holeFrameWidth = 50;          //外框宽
    let holeCircleRadius = 20;        //圆半径
    let holeCrossCircleRadius = 0.5;  //内十字圆弧半径
    let holeCrossFrameLength = 7.5;   //内十字框长度
    let offsetDisType2 = 5            //类型2的偏移距离

    //外框定位点
    let pointFrameDL = point2D.clone().add(new THREE.Vector3(-holeFrameWidth / 2, -holeFrameWidth / 2));
    let pointFrameUL = point2D.clone().add(new THREE.Vector3(-holeFrameWidth / 2, holeFrameWidth / 2));
    let pointFrameUR = point2D.clone().add(new THREE.Vector3(holeFrameWidth / 2, holeFrameWidth / 2));
    let pointFrameDR = point2D.clone().add(new THREE.Vector3(holeFrameWidth / 2, -holeFrameWidth / 2));

    //内十字内定位点
    let pointCrossFrameLUI = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, holeCrossCircleRadius));
    let pointCrossFrameLDI = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, -holeCrossCircleRadius));
    let pointCrossFrameRDI = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, -holeCrossCircleRadius));
    let pointCrossFrameRUI = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, holeCrossCircleRadius));
    //内十字定位点
    let pointCrossFrameLU = point2D.clone().add(new THREE.Vector3(-holeCrossFrameLength, holeCrossCircleRadius));
    let pointCrossFrameLD = point2D.clone().add(new THREE.Vector3(-holeCrossFrameLength, -holeCrossCircleRadius));
    let pointCrossFrameDL = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, -holeCrossFrameLength));
    let pointCrossFrameDR = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, -holeCrossFrameLength));
    let pointCrossFrameRD = point2D.clone().add(new THREE.Vector3(holeCrossFrameLength, -holeCrossCircleRadius));
    let pointCrossFrameRU = point2D.clone().add(new THREE.Vector3(holeCrossFrameLength, holeCrossCircleRadius));
    let pointCrossFrameUR = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, holeCrossFrameLength));
    let pointCrossFrameUL = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, holeCrossFrameLength));
    //内十字圆弧中心
    let pointCrossCircleCenterL = (pointCrossFrameLD.clone().add(pointCrossFrameLU)).multiplyScalar(0.5);
    let pointCrossCircleCenterR = (pointCrossFrameRD.clone().add(pointCrossFrameRU)).multiplyScalar(0.5);
    let pointCrossCircleCenterD = (pointCrossFrameDL.clone().add(pointCrossFrameDR)).multiplyScalar(0.5);
    let pointCrossCircleCenterU = (pointCrossFrameUL.clone().add(pointCrossFrameUR)).multiplyScalar(0.5);

    if(holeType == 2)
    {
      holeCircleRadius = 16;
      let offsetLineType2L = pointFrameDL.clone().add(new THREE.Vector3(0,offsetDisType2));
      let offsetLineType2R = pointFrameDR.clone().add(new THREE.Vector3(0,offsetDisType2));
      //偏置线
      await this.createSketchLine({startPoint: this.getNewPoint(offsetLineType2L), endPoint: this.getNewPoint(offsetLineType2R)});
    }
    let circlePoint = point2D.clone().add(new THREE.Vector3(holeCircleRadius,0));

    //圆
    await this.createCircle({centerPoint:this.getNewPoint(point2D),circlePoint:this.getNewPoint(circlePoint)});
    //外框
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameDL), endPoint: this.getNewPoint(pointFrameUL)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameUL), endPoint: this.getNewPoint(pointFrameUR)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameUR), endPoint: this.getNewPoint(pointFrameDR)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameDR), endPoint: this.getNewPoint(pointFrameDL)});
    //十字
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameUL), endPoint: this.getNewPoint(pointCrossFrameLUI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameLUI), endPoint: this.getNewPoint(pointCrossFrameLU)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterL),startPoint:this.getNewPoint(pointCrossFrameLU),endPoint:this.getNewPoint(pointCrossFrameLD)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameLD), endPoint: this.getNewPoint(pointCrossFrameLDI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameLDI), endPoint: this.getNewPoint(pointCrossFrameDL)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterD),startPoint:this.getNewPoint(pointCrossFrameDL),endPoint:this.getNewPoint(pointCrossFrameDR)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameDR), endPoint: this.getNewPoint(pointCrossFrameRDI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameRDI), endPoint: this.getNewPoint(pointCrossFrameRD)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterR),startPoint:this.getNewPoint(pointCrossFrameRD),endPoint:this.getNewPoint(pointCrossFrameRU)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameRU), endPoint: this.getNewPoint(pointCrossFrameRUI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameRUI), endPoint: this.getNewPoint(pointCrossFrameUR)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterU),startPoint:this.getNewPoint(pointCrossFrameUR),endPoint:this.getNewPoint(pointCrossFrameUL)});
  }
  //根据开叉起终点开叉大小，创建开叉二维
  async createForkLine(pointS, pointE, gapValue) {
    let sketch = this.command.sketch;

    //创建线外框
    let startPntVec = new THREE.Vector3(pointS.x, pointS.y);
    let endPntVec = new THREE.Vector3(pointE.x, pointE.y);
    let dBeveledEdgeLength = gapValue * Math.pow(2, 0.5);
    let dir = pointE.clone().sub(pointS);
    let point1 = this.getOffsetPoint2D(startPntVec, dir.clone().negate(), -45, dBeveledEdgeLength);
    let point2 = this.getOffsetPoint2D(startPntVec, dir.clone().negate(), 45, dBeveledEdgeLength);
    let point3 = this.getOffsetPoint2D(endPntVec, dir, -45, dBeveledEdgeLength);
    let point4 = this.getOffsetPoint2D(endPntVec, dir, 45, dBeveledEdgeLength);

    await sketch.createSketchLineIncrement({startPoint: point1,endPoint: point2,})
    await sketch.createSketchLineIncrement({startPoint: point2,endPoint: point3,})
    await sketch.createSketchLineIncrement({startPoint: point3,endPoint: point4,})
    await sketch.createSketchLineIncrement({startPoint: point4,endPoint: point1,})
  }
  calculateReinforceFramePos(){
    for(let i = 0;i < this.params.allQueueStringerPlane.length;i++){
      if(this.params.allQueueStringerPlane[i].id === this.params.reinforcedStringers[0].id){
        this.params.nNoS = i;
        break;
      }
    }
  }
  getOffsetPoint2D(point, dir, iAngle, offset) {
    //x方向
    let mathDirX = new Vector3(1, 0);
    let angle = Math.acos((mathDirX.clone().dot(dir)) / (mathDirX.length() * dir.length())) * 180 / Math.PI;
    let normal = new Vector3(0, 0, 1);
    //两个向量如果同向或者异向，则无正反之分
    if(angle !== 180 && angle !== 0){
      let crossVector = new THREE.Vector3().crossVectors(mathDirX, dir);
      //如果叉乘向量与旋转轴法向点乘小于0，则angle为反向
      if(normal.clone().dot(crossVector) < 0){
        angle = -angle;
      }
    }
    //所求方向与X向的角度
    let resultAngle = angle + iAngle;
    //换算成弧度
    resultAngle = resultAngle * Math.PI / 180;

    let newPoint2D = new Point(point.x + Math.cos(resultAngle) * offset, point.y + Math.sin(resultAngle) * offset);
    return newPoint2D;
  }
  //测量两个对象距离
  async measureDis(id1, id2) {
    let result = await this.command.evaluate.getMeasureInfoIncrement({geomId: [id1, id2],instanceId:["",""]});

    let distance = 0;
    if(result.data.modelData.data.value.Distance){
      distance = result.data.modelData.data.value.Distance;
    }else{
      distance = result.data.modelData.data.value.MinDistance;
    }

    let point1 = result.data.modelData.data.value.Point1;
    let point2 = result.data.modelData.data.value.Point2;
    //需要判断当前开叉点在位于蒙皮内部还是外部，如果是外部，则距离为负
    //通过创建三维的内方向进行判断
    let pointNear1 = new THREE.Vector3(point1[0],point1[1],point1[2]);
    let pointNear2 = new THREE.Vector3(point2[0],point2[1],point2[2]);

    let dir21 = pointNear1.clone().sub(pointNear2);
    let value = dir21.dot(this.innerDir);
    return distance * (value > 0 ? 1 : -1);
  }
  //创建草图线
  async createSketchLine(params) {
    let line2DAdd = await this.command.sketch.createSketchLineIncrement({startPoint: params.startPoint, endPoint: params.endPoint});
    let line = await this.getAddElement(line2DAdd,ElementType.CURVE);
    return line;
  }
  async createCircle(params){
    let circle2DAdd = await this.command.sketch.createCircleIncrement({centerPoint:params.centerPoint,circlePoint:params.circlePoint});
    let circle = await this.getAddElement(circle2DAdd,ElementType.CURVE);
    return circle;
  }
  async createArc(params){
    await this.command.sketch.createArcByCenterIncrement({
      centerPoint: params.centerPoint,
      startPoint: params.startPoint,
      endPoint: params.endPoint
    });
  }
  //创建草图参考线
  async createReferenceLine(params) {
    let startPoint = this.dealObject(params.startPoint);
    let endPoint = this.dealObject(params.endPoint);
    let line2DAdd = await this.command.sketch.createReferenceLineIncrement({startPoint: startPoint,endPoint: endPoint});
    let line = await this.getAddElement(line2DAdd,ElementType.CURVE);
    return line;
  }
  //创建草图点
  async createPoint(params){
    if(Math.abs(params.x) < 0.001){
      params.x = 0;
    }
    if(Math.abs(params.y) < 0.001){
      params.y = 0;
    }

    let point2DAdd = await this.command.sketch.createPointIncrement(params);
    let point = await this.getAddElement(point2DAdd,ElementType.POINT);
    return point;
  }
  //ThreeJs的vector3转为Point
  getNewPoint(point){
    if(Math.abs(point.x) < 0.001){
      point.x = 0;
    }
    if(Math.abs(point.y) < 0.001){
      point.y = 0;
    }
    if(Math.abs(point.z) < 0.001){
      point.z = 0;
    }

    let newPoint = new Point(point.x,point.y,point.z);
    return newPoint;
  }
  //点到一组平面获取最近的平面
  getMinDisPlane(point,planeList){
    let minDis = 1000000;
    let minNo = 0;
    for(let planeIndex = 0;planeIndex < planeList.length;planeIndex++){
      let plane = planeList[planeIndex];
      let planeNormal = this.getThreeVector3(plane.params.normal);
      let planeOrigin = this.getThreeVector3(plane.params.origin);

      //为方便记录点是在平面的哪个方向
      //当前平面原点指向下一平面原点为前进方向，平面法向与前进方向点乘为正为正向，对于最后一个的前进方向为上一平面指向下一平面方向
      let tempDirFront = planeNormal;
      if(planeList.length === 1){
        //当当前面为框站位面时，使用航向作为前进方向
        tempDirFront = this.params.dirCourse;
      }else if(planeIndex === planeList.length - 1){
        let lastPlaneOrigin = this.getThreeVector3(planeList[planeList.length - 2].params.origin);
        tempDirFront = (planeOrigin.clone().sub(lastPlaneOrigin)).normalize();
      }else{
        let nextPlaneOrigin = this.getThreeVector3(planeList[planeIndex + 1].params.origin)
        tempDirFront = (nextPlaneOrigin.clone().sub(planeOrigin)).normalize();
      }
      //方向系数，如果前进方向与当前平面方向相同为正，相反为负
      let nDirCoefficient = 1;
      if(planeNormal.clone().dot(tempDirFront) < 0){
        nDirCoefficient = -1;
      }
      //获取带有正负向的距离
      let tempDis = this.getDisFromPointToPlane(planeOrigin,planeNormal,point);
      tempDis *= nDirCoefficient;
      if(Math.abs(tempDis) < Math.abs(minDis)){
        minDis = tempDis;
        minNo = planeIndex;
      }
    }

    let minDisPlane = {
      dis:minDis,
      minNo:minNo,
    }
    return minDisPlane;
  }
  //计算二维展开图中用到的参数
  async calculateParametersValue(params, surface) {
    //框站位
    let frameNormal = params.frames[0]?.params?.normal;
    let frameNormalVec = new THREE.Vector3(frameNormal.x, frameNormal.y, frameNormal.z);
    let stringerNormal = params?.stringers[0]?.params?.normal;
    let stringerNormalVec = new THREE.Vector3(stringerNormal.x, stringerNormal.y, stringerNormal.z);
    let framePos = this.getPosition(params?.frames[0]);
    let stringerPos = this.getPosition(params?.stringers[0]);
    if (!frameNormalVec || !stringerNormalVec) {
      return;
    }

    params.framePos = framePos;
    params.frameNormal = frameNormalVec;
    params.stringerPos = stringerPos;
    params.stringerNormal = stringerNormalVec;

    //计算长桁间的交线及相邻长桁的距离
    await this.computeStringersLength(params, surface);
  }
  //获取中间的长桁线之间的距离
  async computeStringersLength(params, surface) {
    let face = await this.getFace(surface);
    if (!face) {
      return;
    }
    let sketch = this.command.sketch;
    let sortPlaneList = params.allQueueStringerPlane;
    let lastStartPoint = null;
    let stringerLength = 0;
    let stringerDisList = [];
    for (let i = 0; i < sortPlaneList.length; i++) {
      let planeEle = sortPlaneList[i];
      //通过该平面求交叉曲线
      await sketch.createSketchIncrement({
        sketchName: '',
        datumId: planeEle.id,
      })
      let intersectCurveRes = await sketch.createIntersectCurveIncrement({
        faceIds: [face.id],
      })
      await sketch.exitSketchIncrement();
      //隐藏草图
      let featureId = this.getFeatureId(intersectCurveRes);
      //await this.setFeatureVisible(featureId,false);
      let addElements = intersectCurveRes?.data?.modelData?.data?.addElements;
      if (addElements) {
        for (let j = 0 ; j < addElements.length; j++) {
          let ele = addElements[j];
          if (ele.type === ElementType.CURVE || ele.type === ElementType.EDGE) {
            let elementObj = await this.query.getElementsByIds([ele.id]);
            let elements = elementObj?.data?.elements;
            if (!elements || elements.length === 0) {
              return;
            }
            let startPoint = elements[0]?.params?.startPoint;
            let startPointVec = new Vector3(startPoint[0], startPoint[1], startPoint[2]);
            if (!lastStartPoint) {
              lastStartPoint = startPointVec;
            }
            let len = lastStartPoint.clone().sub(startPointVec).length();
            lastStartPoint = startPointVec;
            planeEle.length = len;
            stringerLength += len;
            stringerDisList.push(stringerLength);
            break;
          }
        }
      }

      //删除当前草图
      await this.command.common.deleteFeatureIncrement({featureIds: [featureId]});
    }
    //params.stringerLength = stringerLength;
    params.stringerDisList = stringerDisList;
  }
  //曲面复制
  async copySurface(params){
    //拷贝曲面
    let surfaceTemp = params.skins[0];
    //复制后对复制曲面进行操作
    let copySurface = await this.command.surface.copySurfaceIncrement({surfaceIds: [surfaceTemp.id], instanceIds: [0]}, "复制曲面");

    let featureId = this.getFeatureId(copySurface);
    await this.setFeatureVisible(featureId,false);
    return copySurface;
  }
  //站位面排序
  async queueStringerPlane(params){
    //如果有加强长桁，将加强长桁一起进行排序
    let selectStringers = params.stringers.slice();
    if(this.params.bReinforceFrame && params.reinforcedStringers.length > 0){
      selectStringers.push(params.reinforcedStringers[0]);
    }

    //对当前选取的长桁站位进行排序
    let selectPlaneQueueList = this.queuePlaneList(selectStringers);

    //通过第一个和最后一个平面获取起止平面
    let allStringerPlane = await this.getPlanesBetweenSide(selectPlaneQueueList[0],selectPlaneQueueList[selectPlaneQueueList.length - 1]);

    return allStringerPlane;
  }
  //获取交叉曲线
  async getIntersectCurve(plane,surface){
    let face = await this.getFace(surface);
    if (!face) {
      return;
    }

    let sketch = this.command.sketch;
    //通过该平面求交叉曲线
    await sketch.createSketchIncrement({
      sketchName: '',
      datumId: plane.id,
    })

    let intersectCurveRes = await sketch.createIntersectCurveIncrement({
      faceIds: [face.id],
    })

    await sketch.exitSketchIncrement();

    //隐藏草图
    let featureId = this.getFeatureId(intersectCurveRes);
    let res = await this.toolQuery.getEntitiesByFeatureId(featureId);
    if (res && res?.data?.entities?.length > 0) {
      let entityId = res?.data?.entities[0].id;
      await this.command.common.setEntityVisibleIncrement({entityIds:[entityId], status: 0});
    }
    let addElements = intersectCurveRes?.data?.modelData?.data?.addElements;
    if (addElements) {
      for (let j = 0 ; j < addElements.length; j++) {
        let ele = addElements[j];
        if (ele.type === ElementType.CURVE || ele.type === ElementType.EDGE) {
          let elementObj = await this.query.getElementsByIds([ele.id]);
          let elements = elementObj?.data?.elements;
          if (!elements || elements.length === 0) {
            return;
          }
          return elements[0];
        }
      }
    }
  }

  calculatePolyLine(point1,point2,point3,dis,extendRatio){
    let line1 = this.getOffsetLine(point1,point2,dis);
    let line2 = this.getOffsetLine(point2,point3,dis);
    //外扩线交点
    let intersectPoint = this.getIntersectPoint2(line1.point1,line1.point2,line2.point1,line2.point2);

    //中间点到两侧点的距离向量
    let vect21 = point1.clone().sub(point2);
    let vect23 = point3.clone().sub(point2);

    let point1ExtendPoint = intersectPoint.clone().add(vect21.clone().multiplyScalar(extendRatio));
    let point3ExtendPoint = intersectPoint.clone().add(vect23.clone().multiplyScalar(extendRatio));

    let polyLineParam = {point1:point1ExtendPoint,point2:intersectPoint,point3:point3ExtendPoint};
    return polyLineParam;
  }

  //一组点，求外扩点组合
  getOffsetPointList(pointList,disW,disH){
    let pointListNew = [];
    for(let i = 0;i < pointList.length;i++){
      let point2No = i + 1;
      let point3No = i + 2;
      if(point2No >= pointList.length){
        point2No -= pointList.length;
      }
      if(point3No >= pointList.length){
        point3No -= pointList.length;
      }
      //在序号为1、4的时候，横向纵向距离不同
      let dis1 = disW;
      let dis2 = disW;
      if(i == 1 || i == 4){
        dis2 = disH;
      }else if(i == 2 || i == 5){
        dis1 = disH;
      }


      let point1 = this.getThreeVector3(pointList[i]);
      let point2 = this.getThreeVector3(pointList[point2No]);
      let point3 = this.getThreeVector3(pointList[point3No]);

      let line1 = this.getOffsetLine(point1,point2,dis1);
      let line2 = this.getOffsetLine(point2,point3,dis2);

      let intersectPoint = this.getIntersectPoint2(line1.point1,line1.point2,line2.point1,line2.point2);
      pointListNew.push(intersectPoint);
    }
    return pointListNew;
  }

  //两条线求交点
  getIntersectPoint2(point11,point12,point21,point22){
    //判断两个点不平行
    let dir1 = point12.clone().sub(point11);
    let dir2 = point22.clone().sub(point21);
    dir1.normalize();
    dir2.normalize();

    let dotValue = dir1.clone().dot(dir2);
    if(Math.abs(dotValue) > 0.999999){
      return;
    }

    let a = point12.y - point11.y;
    let b = point11.x - point12.x;
    let c = point11.x * point12.y - point12.x * point11.y;
    let d = point22.y - point21.y;
    let e = point21.x - point22.x;
    let f = point21.x * point22.y - point22.x * point21.y;

    let denominator = b * d - a * e;
    let x = (b * f - e * c) / denominator;
    let y = (d * c - a * f) / denominator;
    return new THREE.Vector3(x,y);
  }

  //在空间中，以第一个点到第二个点方向的顺时方向偏移一定距离形成新的线,normal为空时为(0,0,1),即二维
  getOffsetLine(point1,point2,dis,normal = null){
    if(!normal){
      normal = new THREE.Vector3(0,0,1);
    }

    //point1，point2，需要和normal垂直
    let dir = point2.clone().sub(point1);
    dir.normalize();
    let value = dir.clone().dot(normal);
    if(Math.abs(value) > 0.001){
      return;
    }

    //获取顺向偏移方向
    let offsetDir = new THREE.Vector3().crossVectors(dir,normal);
    offsetDir.normalize();

    let offsetVec = offsetDir.multiplyScalar(dis);

    let newPoint1 = point1.clone().add(offsetVec);
    let newPoint2 = point2.clone().add(offsetVec);
    let param = {point1:newPoint1,point2:newPoint2};
    return param;
  }

  //裁剪曲面
  async trimSurface(surface, stringer1,stringer2) {
    if (!surface || !stringer1 || !stringer2) {
      return;
    }
    let face = await this.getFace(surface);
    if(!face){
      return;
    }

    let pos1, pos2, normal1, normal2, entityId1, entityId2;
    if (stringer1.type === ElementType.FACE) {
      pos1 = stringer1?.params?.position;
    } else if (stringer1.type === ElementType.DATUMPLANE) {
      pos1 = stringer1?.params?.origin;
    }
    normal1 = stringer1?.params?.normal;
    entityId1 = stringer1?.params?.entityRefId;

    if (stringer2.type === ElementType.FACE) {
      pos2 = stringer2?.params?.position;
    } else if (stringer2.type === ElementType.DATUMPLANE) {
      pos2 = stringer2?.params?.origin;
    }
    normal2 = stringer2?.params?.normal;
    entityId2 = stringer2?.params?.entityRefId;

    if (!pos1 || !pos2 || !normal1 || !normal2 || !entityId1 || !entityId2) {
      return;
    }

    let res = await this.query.getEntitiesByIds([entityId1, entityId2]);
    let trimElement = [];
    let surfaceElement = [];
    surfaceElement.push(face);
    if (res && res?.data?.entities.length > 1) {
      let entity1 = res?.data?.entities[0];
      let entity2 = res?.data?.entities[1];
      trimElement.push(entity1);
      trimElement.push(entity2);
    }

    let params = {
      trimElement: trimElement,
      surfaceElement: surfaceElement,
    }
    let previewResult = await this.toolQuery.executePreviewTrimSurface(params);
    let keepTags = [];
    let newSrfDataArray, oldSrfDataArray;
    if (previewResult) {
      let position1 = new THREE.Vector3(pos1.x, pos1.y, pos1.z);
      let position2 = new THREE.Vector3(pos2.x, pos2.y, pos2.z);
      let elementNormal1 = new THREE.Vector3(normal1.x, normal1.y, normal1.z);
      let elementNormal2 = new THREE.Vector3(normal2.x, normal2.y, normal2.z);

      newSrfDataArray = previewResult?.data?.elements?.newSrfData;
      oldSrfDataArray = previewResult?.data?.elements?.oldSrfData;
      let lastLength = 0;
      let index = -1;
      for (let i = 0; i < newSrfDataArray?.length; i++) {
        let boxCenter = await this.toolQuery.getMiddleElementBoxCenterPoint(newSrfDataArray[i]);
        let vector1 = position1.clone().sub(boxCenter?.data);
        let vector2 = position2.clone().sub(boxCenter?.data);
        let dir1 = vector1.clone().dot(elementNormal1);
        let dir2 = vector2.clone().dot(elementNormal2);
        let dir3 = elementNormal1.clone().dot(elementNormal2);
        if ((dir3 > 0 && dir1 * dir2 < 0) || (dir3 < 0 && dir1 * dir2 > 0)) {
          let length = vector1.length();
          if (lastLength === 0) {
            lastLength = length;
            index = i;
            keepTags.push(1);
          } else {
            if (lastLength < length) {
              keepTags.push(0);
            } else {
              keepTags[index] = 0;
              lastLength = length;
              index = i;
              keepTags.push(1);
            }
          }
        } else {
          keepTags.push(0);
        }
      }
    }
    //执行裁剪曲面
    let limitIds = [];
    trimElement.forEach(entity => {
      limitIds.push(entity.id);
    })
    let surfaceIds = [];
    surfaceElement.forEach(ele => {
      surfaceIds.push(ele.id);
    })
    let surfaceResult = await this.command.surface.trimSurfaceIncrement({
      limitIds: limitIds,
      surfaceIds: surfaceIds,
      keepMode: 1,
      keepTags: keepTags,
      oldSurfaceIds: oldSrfDataArray,
      newSurfaceIds: newSrfDataArray,
    })
    return surfaceResult;
  }

  //创建包框扫掠
  async createFrameModelSweep(params,dirCourse,guideCurve,stringerPlane1,stringerPlane2){
    //草图的法向求解
    let stringer1Origin = new THREE.Vector3(stringerPlane1.params.origin.x,stringerPlane1.params.origin.y,stringerPlane1.params.origin.z);
    let stringer1Normal = new THREE.Vector3(stringerPlane1.params.normal.x,stringerPlane1.params.normal.y,stringerPlane1.params.normal.z);
    let stringer2Origin = new THREE.Vector3(stringerPlane2.params.origin.x,stringerPlane2.params.origin.y,stringerPlane2.params.origin.z);
    let stringer2Normal = new THREE.Vector3(stringerPlane2.params.normal.x,stringerPlane2.params.normal.y,stringerPlane2.params.normal.z);

    if(!stringer1Origin || !stringer1Normal || !stringer2Origin || !stringer2Normal){
      return;
    }

    //草图的法向朝向应该是指向于另一个平面，即如果当前是起始面则法向指向终止面，如果当前是终止面则法向指向起始面
    let dirSE = stringer2Origin.clone().sub(stringer1Origin);
    //以第一个面为草图的基准面
    let sketchNormal = stringer1Normal;
    let dotValueSE = dirSE.clone().dot(stringer1Normal);
    let bReversNormal = false;
    if(dotValueSE < 0){
      sketchNormal = stringer1Normal.clone().negate();
      bReversNormal = true;
    }
    sketchNormal.normalize();

    //第一个长桁站位内方向为初始长桁站位与框站位相交线在蒙皮内向的方向上
    let innerDir = new THREE.Vector3().crossVectors(sketchNormal,dirCourse);
    innerDir.normalize();
    //在向内的方向上距离其他长桁站位面应该比原点近
    let pointTemp = stringer1Origin.clone().add(innerDir.clone().multiplyScalar(1));
    //草图原点到另一面距离
    let disPointToOtherPlane = Math.abs(this.getDisFromPointToPlane(stringer2Origin,stringer2Normal,stringer1Origin));
    //前进一点后到另一面距离
    let disTempToOtherPlane = Math.abs(this.getDisFromPointToPlane(stringer2Origin,stringer2Normal,pointTemp));
    //求出当前长桁站位向飞机内部的分量方向
    if(disTempToOtherPlane > disPointToOtherPlane){
      innerDir.negate();
    }
    this.innerDir = innerDir;

    //通过航向进行矫正后的草图法向
    let sketchNormalModify = (new THREE.Vector3().crossVectors(dirCourse,innerDir)).normalize();

    //计算包框截面
    let sectionPointList = this.calculateSectionPoint(params);

    //创建草图
    let sketchPlaneId = stringerPlane1.id;

    //判断当前选定的草图平面上，引导线哪个端点在草图平面上
    let startOrEndOnPlane = this.getStartOrEndOnPlane(guideCurve,stringer1Origin,stringer1Normal);

    //创建具有原点和上方向以及法向的草图平面
    //需要创建一个原点然后生成具有指定原点的草图
    let originPointId = await this.createPointByCurve(guideCurve,startOrEndOnPlane * 100);

    let yyDirection = new Direction();
    //Y向无论何时都应该指向内
    yyDirection.setPoint(new Point(0,0,0),new Point(innerDir.x,innerDir.y,innerDir.z)); //构造方法啥也不是

    let reverseNormal = 0;
    if(stringer1Normal.clone().dot(sketchNormalModify) < 0){
      reverseNormal = 1;
      //yyDirection.setPoint(new Point(0,0,0),new Point(-innerDir.x,-innerDir.y,-innerDir.z));
    }
    await this.command.sketch.createSketchIncrement({sketchName: '',
      datumId: sketchPlaneId,
      originRefId:originPointId,
      yDirection:yyDirection,
      reverseNormal:reverseNormal});

    //创建所有草图折线
    for(let pointIndex = 0;pointIndex < sectionPointList.length;pointIndex++)
    {
      let startPoint = sectionPointList[pointIndex];
      let endPoint;
      if(pointIndex === sectionPointList.length - 1){
        endPoint = sectionPointList[0];
      }else{
        endPoint = sectionPointList[pointIndex + 1];
      }
      await this.createSketchLine({
        startPoint: new Point(this.dealValue(startPoint.x), this.dealValue(startPoint.y)),
        endPoint: new Point(this.dealValue(endPoint.x), this.dealValue(endPoint.y))
      });
    }

    let sketch = await this.command.sketch.exitSketchIncrement();

    //进行扫描凸台创建
    let sketchFeatureId = this.getFeatureId(sketch);
    let res = await this.toolQuery.getEntitiesByFeatureId(sketchFeatureId);
    let sweepSolid;
    if (res && res?.data?.entities?.length > 0) {
      let entityId = res?.data?.entities[0].id;
      //扫描凸台
      sweepSolid = await this.command.solid.sweepIncrement({
        sweepType: 0,
        sweepProfile: entityId,
        sweepPath: [guideCurve.id],
        sweepDirection: -1,
      }, "")
    }

    return sweepSolid;
  }
  //创建加强包框放样
  async createFrameModelLoft(params,dirCourse,guideCurve,stringerPlane1,stringerPlane2){
    //草图的法向求解
    let stringer1Origin = new THREE.Vector3(stringerPlane1.params.origin.x,stringerPlane1.params.origin.y,stringerPlane1.params.origin.z);
    let stringer1Normal = new THREE.Vector3(stringerPlane1.params.normal.x,stringerPlane1.params.normal.y,stringerPlane1.params.normal.z);
    let stringer2Origin = new THREE.Vector3(stringerPlane2.params.origin.x,stringerPlane2.params.origin.y,stringerPlane2.params.origin.z);
    let stringer2Normal = new THREE.Vector3(stringerPlane2.params.normal.x,stringerPlane2.params.normal.y,stringerPlane2.params.normal.z);

    if(!stringer1Origin || !stringer1Normal || !stringer2Origin || !stringer2Normal){
      return;
    }

    //草图的法向朝向应该是指向于另一个平面，即如果当前是起始面则法向指向终止面，如果当前是终止面则法向指向起始面
    let dirSE = stringer2Origin.clone().sub(stringer1Origin);
    //以第一个面为草图的基准面
    let sketchNormal = stringer1Normal;
    let dotValueSE = dirSE.clone().dot(stringer1Normal);
    if(dotValueSE < 0){
      sketchNormal = dotValueSE.clone().negate();
    }
    sketchNormal.normalize();

    //第一个长桁站位内方向为初始长桁站位与框站位相交线在蒙皮内向的方向上
    let innerDir = new THREE.Vector3().crossVectors(sketchNormal,dirCourse);
    innerDir.normalize();
    //在向内的方向上距离其他长桁站位面应该比原点近
    let pointTemp = stringer1Origin.clone().add(innerDir.clone().multiplyScalar(1));
    //草图原点到另一面距离
    let disPointToOtherPlane = Math.abs(this.getDisFromPointToPlane(stringer2Origin,stringer2Normal,stringer1Origin));
    //前进一点后到另一面距离
    let disTempToOtherPlane = Math.abs(this.getDisFromPointToPlane(stringer2Origin,stringer2Normal,pointTemp));
    //求出当前长桁站位向飞机内部的分量方向
    if(disTempToOtherPlane > disPointToOtherPlane){
      innerDir.negate();
    }

    //通过航向进行矫正后的草图法向
    let sketchNormalModify = (new THREE.Vector3().crossVectors(dirCourse,innerDir)).normalize();

    //计算包框截面
    let sectionPointList = this.calculateSectionPoint(params);

    //创建草图
    let sketchPlaneId = stringerPlane1.id;
    //判断当前选定的草图平面上，引导线哪个端点在草图平面上
    let startOrEndOnPlane = this.getStartOrEndOnPlane(guideCurve,stringer1Origin,stringer1Normal);

    //创建具有原点和上方向以及法向的草图平面
    //需要创建一个原点然后生成具有指定原点的草图
    let originPointId = await this.createPointByCurve(guideCurve,startOrEndOnPlane * 100);

    let yyDirection = new Direction();
    yyDirection.setPoint(new Point(0,0,0),new Point(innerDir.x,innerDir.y,innerDir.z)); //构造方法啥也不是

    let reverseNormal = 0;
    if(stringer1Normal.clone().dot(sketchNormalModify) < 0){
      reverseNormal = 1;
      //yyDirection.setPoint(new Point(0,0,0),new Point(-innerDir.x,-innerDir.y,-innerDir.z));
    }
    await this.command.sketch.createSketchIncrement({sketchName: '',
      datumId: sketchPlaneId,
      originRefId:originPointId,
      yDirection:yyDirection,
      reverseNormal:reverseNormal});

    //创建所有草图折线
    for(let pointIndex = 0;pointIndex < sectionPointList.length;pointIndex++)
    {
      let startPoint = sectionPointList[pointIndex];
      let endPoint;
      if(pointIndex === sectionPointList.length - 1){
        endPoint = sectionPointList[0];
      }else{
        endPoint = sectionPointList[pointIndex + 1];
      }
      await this.createSketchLine({
        startPoint: new Point(this.dealValue(startPoint.x), this.dealValue(startPoint.y)),
        endPoint: new Point(this.dealValue(endPoint.x), this.dealValue(endPoint.y))
      });
    }

    let sketch = await this.command.sketch.exitSketchIncrement();

    //进行扫描凸台创建
    let sketchFeatureId = this.getFeatureId(sketch);
    let res = await this.toolQuery.getEntitiesByFeatureId(sketchFeatureId);
    let sweepSolid;
    if (res && res?.data?.entities?.length > 0) {
      let entityId = res?.data?.entities[0].id;
      //扫描凸台
      sweepSolid = await this.command.solid.sweepIncrement({
        sweepType: 0,
        sweepProfile: entityId,
        sweepPath: [guideCurve.id],
        sweepDirection: -1,
      }, "")
    }

    return sweepSolid;
  }

  //通过航向描述获取航向
  getDirectionCourse(courseNo){
    let dirCourse;
    if(courseNo === 11){
      dirCourse = new THREE.Vector3(1,0,0);
    }else if(courseNo === 12){
      dirCourse = new THREE.Vector3(-1,0,0);
    }else if(courseNo === 21){
      dirCourse = new THREE.Vector3(0,1,0);
    }else if(courseNo === 22){
      dirCourse = new THREE.Vector3(0,-1,0);
    }else if(courseNo === 31){
      dirCourse = new THREE.Vector3(0,0,1);
    }else if(courseNo === 32){
      dirCourse = new THREE.Vector3(0,0,-1);
    }
    return dirCourse;
  }
  //计算包框截面草图上的点
  calculateSectionPoint(params){
    let frameHeight = params.standardFrameHeight - params.stringerHeight;
    let thickness = params.solidThickness;
    let frameEdgeWidth = params.frameEdgeWidth;

    let pointI1 = new Point(params.skinOffsetP,0);
    let pointI2 = new Point(params.innerOffsetP,frameHeight);
    let pointI3 = new Point(-params.innerOffsetN,frameHeight);
    let pointI4 = new Point(-params.skinOffsetN,0);
    let pointO1 = new Point(params.skinOffsetP + thickness,0);
    let pointO2 = new Point(params.innerOffsetP + thickness,frameHeight + thickness);
    let pointO3 = new Point(-params.innerOffsetN - thickness,frameHeight + thickness);
    let pointO4 = new Point(-params.skinOffsetN - thickness,0);
    //内侧点认为是角点
    let dTangentAlphaR = Math.atan((Math.abs(frameEdgeWidth) + params.innerOffsetP - params.skinOffsetP) / frameHeight);
    let dTangentAlphaL = Math.atan((Math.abs(frameEdgeWidth) + params.innerOffsetN - params.skinOffsetN) / frameHeight);
    //认为框缘宽度是朝向飞机航向的方向，默认是向右，
    //逆时针方向计算，右侧两个点由右侧框缘宽度进行计算，草图点顺序是I1、I2、I3、I4、O4、O3、O2、O1
    if(frameEdgeWidth > 0 || (frameEdgeWidth < 0 && params.bFrameEdgeSymmetry)){
      pointI2.x = params.innerOffsetP + Math.abs(frameEdgeWidth);

      pointO1.x = pointI1.x + thickness / Math.cos(dTangentAlphaR);

      pointO2.x = pointO1.x + pointO2.y * Math.tan(dTangentAlphaR);
    }
    //如果为对称或者左侧Z字钢，左侧也进行延伸
    if(frameEdgeWidth < 0 || (frameEdgeWidth > 0 && params.bFrameEdgeSymmetry)){
      pointI3.x = -(params.innerOffsetN + Math.abs(frameEdgeWidth));

      pointO4.x = pointI4.x - thickness / Math.cos(dTangentAlphaL);

      pointO3.x = pointO4.x - pointO3.y * Math.tan(dTangentAlphaL);
    }

    //隔框厚度
    //let frameThickness = 2;
    //隔框截面高度
    //let frameHeight = 60;
    //框缘宽度
    //let frameWidth = 15;
    //包框隔热隔声厚度
    //let thickness = 15;
    //是否对称隔框
    //let bFrameSymmetry = false;

    // let pointI1 = new Point(frameThickness,0);
    // let pointI2 = new Point(frameThickness,frameHeight);
    // let pointI3 = new Point(-frameThickness,frameHeight);
    // let pointI4 = new Point(-frameThickness,0);
    // let pointO1 = new Point(frameThickness + thickness,0);
    // let pointO2 = new Point(frameThickness + thickness,frameHeight + thickness);
    // let pointO3 = new Point(-frameThickness - thickness,frameHeight + thickness);
    // let pointO4 = new Point(-frameThickness - thickness,0);

    // //内侧点认为是角点
    // let dTangentAlpha = Math.atan(Math.abs(frameWidth) / frameHeight);
    // if(frameWidth > 0 || (frameWidth < 0 && bFrameSymmetry))
    // {
    //   let dPointO1X = frameThickness + thickness / Math.cos(dTangentAlpha);
    //   pointO1.x = dPointO1X;
    //   pointO1.y = 0;
    //
    //   let dPointI1X = frameThickness;
    //   let dPointI1Y = 0;
    //   pointI1.x = dPointI1X;
    //   pointI1.y = dPointI1Y;
    //
    //   let dPointI2X = Math.abs(frameWidth);
    //   let dPointI2Y = frameHeight;
    //   pointI2.x = dPointI2X;
    //   pointI2.y = dPointI2Y;
    //
    //   let dPointO2Y = frameHeight + thickness;
    //   let dPointO2X = dPointO1X + dPointO2Y * Math.tan(Math.abs(dTangentAlpha));
    //   pointO2.x = dPointO2X;
    //   pointO2.y = dPointO2Y;
    // }
    // if(frameWidth < 0 || (frameWidth > 0 && bFrameSymmetry))
    // {
    //   let dPointO4X = -frameThickness - thickness / Math.cos(dTangentAlpha);
    //   pointO4.x = dPointO4X;
    //   pointO4.y = 0;
    //
    //   let dPointI4X = frameThickness;
    //   let dPointI4Y = 0;
    //   pointI4.x = dPointI4X;
    //   pointI4.y = dPointI4Y;
    //
    //   let dPointI3X = -Math.abs(frameWidth);
    //   let dPointI3Y = frameHeight;
    //   pointI3.x = dPointI3X;
    //   pointI3.y = dPointI3Y;
    //
    //   let dPointO3Y = frameHeight + thickness;
    //   let dPointO3X = -dPointO4X - dPointO3Y * Math.tan(Math.abs(dTangentAlpha));
    //   pointO3.x = dPointO3X;
    //   pointO3.y = dPointO3Y;
    // }

    let listPoint = [];
    listPoint.push(pointI1);
    listPoint.push(pointI2);
    listPoint.push(pointI3);
    listPoint.push(pointI4);
    listPoint.push(pointO4);
    listPoint.push(pointO3);
    listPoint.push(pointO2);
    listPoint.push(pointO1);

    //根据长桁高度进行高度偏移
    let newListPoint = [];
    listPoint.forEach(point => {
      newListPoint.push(new THREE.Vector3(point.x,point.y + params.stringerHeight));
    })
    listPoint = newListPoint;

    return listPoint;
  }

  getFeatureId(result) {
    let currentFeature = result?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      return currentFeature[0].id;
    }
  }
  async getFace(result) {
    let face;
    result?.data?.modelData?.data?.addElements?.forEach(ele => {
      if (ele.type === ElementType.FACE || ele.type === ElementType.SURFACE) {
        face = ele;
        return face;
      }
    })
    return face;
  }

  //获取两个长桁间的所有长桁基准面
  async getPlanesBetweenSide(stringer1,stringer2) {
    if (!stringer1 || !stringer2) {
      return;
    }
    let betweenPlanes = [];
    betweenPlanes.push(stringer1);
    let planes = await this.toolQuery.getPlaneAndDatumPlane();
    for (let i = 0; i < planes?.data?.length; i++) {
      let plane = planes.data[i];
      if (!plane || plane.id === stringer1.id || plane.id === stringer2.id) {
        continue;
      }
      if (!this.getPlaneIsInTwoPlane(plane, stringer1, stringer2)) {
        continue;
      }
      betweenPlanes.push(plane);
    }
    betweenPlanes.push(stringer2);
    return betweenPlanes;
  }
  //判断平面是否在两个平面中间
  getPlaneIsInTwoPlane(plane, stringer1, stringer2) {
    let origin = plane?.params?.origin;
    let mathPointOrigin = new THREE.Vector3(origin.x, origin.y, origin.z);
    let origin1 = stringer1?.params?.origin;
    let mathPointOrigin1 = new THREE.Vector3(origin1.x, origin1.y, origin1.z);
    let origin2 = stringer2?.params?.origin;
    let mathPointOrigin2 = new THREE.Vector3(origin2.x, origin2.y, origin2.z);
    let normal = plane?.params?.normal;
    let mathDir = new THREE.Vector3(normal.x, normal.y, normal.z);
    let normal1 = stringer1?.params?.normal;
    let mathDir1 = new THREE.Vector3(normal1.x, normal1.y, normal1.z);
    let normal2 = stringer2?.params?.normal;
    let mathDir2 = new THREE.Vector3(normal2.x, normal2.y, normal2.z);
    //处于两个平面中间的平面原点应该为：两侧平面原点指向该平面原点的向量，与两平面法向（互相指向对面平面）应该同向
    let mathDir1To2 = mathPointOrigin2.clone().sub(mathPointOrigin1);
    let mathDir2To1 = mathDir1To2.clone().negate();

    //平面1法向与平面12原点指向是否一致
    let dValue12 = mathDir1To2.clone().dot(mathDir1);
    //不一致则进行翻转
    if(dValue12 < 0)
    {
      mathDir1 = mathDir1.clone().negate();
    }
    //平面2法向与平面21原点指向是否一致
    let dValue21 = mathDir2To1.clone().dot(mathDir2);
    //不一致则进行翻转
    if(dValue21 < 0)
    {
      mathDir2 = mathDir2.clone().negate();
    }

    //两平面原点到平面的原点
    let math1To0 = mathPointOrigin.clone().sub(mathPointOrigin1);
    let math2To0 = mathPointOrigin.clone().sub(mathPointOrigin2);

    //法向判断，如果是中间平面，mathDir1 X planeNormal 与 planeNormal X -mathDir2应该是同向
    let crossValue1 = new THREE.Vector3().crossVectors(mathDir1,mathDir);
    let crossValue2 = new THREE.Vector3().crossVectors(mathDir,mathDir2.clone().negate());
    let crossDot = crossValue1.clone().dot(crossValue2);

    //如果平面法向与限制平面原点到平面原点的向量均符合>0则该平面符合条件
    if((math1To0.clone().dot(mathDir1) > 0 && math2To0.clone().dot(mathDir2) > 0) && crossDot > 0)
    {
      return true;
    }

    return false;
  }

  //长桁排序
  queuePlaneList(planeList) {
    if (planeList.length <= 0) {
      return;
    }
    //第一个长桁与其它长桁的交点
    let plane = planeList[0];
    let origin = plane?.params?.origin;
    let normal = plane?.params?.normal;
    let originVec = new THREE.Vector3(origin.x, origin.y, origin.z);
    let normalVec = new THREE.Vector3(normal.x, normal.y, normal.z);
    for (let i = 0; i < planeList.length; i++) {
      let stringer = planeList[i];
      let stringerOrigin = stringer?.params?.origin;
      let stringerNormal = stringer?.params?.normal;
      let stringerOriginVec = new THREE.Vector3(stringerOrigin.x, stringerOrigin.y, stringerOrigin.z);
      let stringerNormalVec = new THREE.Vector3(stringerNormal.x, stringerNormal.y, stringerNormal.z);
      let intersectPnt = this.getIntersectPoint(originVec, normalVec, stringerOriginVec, stringerNormalVec);
      stringer.intersectPoint = intersectPnt;
    }
    planeList.sort((plane1, plane2) => {
      let length1 = originVec.clone().sub(plane1.intersectPoint).length();
      let length2 = originVec.clone().sub(plane2.intersectPoint).length();
      if (length1 < length2) {
        return -1;
      } else if (length1 > length2) {
        return 1;
      } else {
        return 0;
      }
    })
    return planeList;
  }
  //根据线端点创建一个点
  async createPointByCurve(curve,dOffsetPercentage = 0) {
    let originPoint = await this.command.datum.createPointByCurveIncrement({
      referenceEntities: curve.id,
      multiplePntsType: 1,
      referenceValue: dOffsetPercentage
    });
    let featureId = this.getFeatureId(originPoint);
    let pointElementsRes = await this.query.getElementsByFeatureId(featureId);
    let pointElements = pointElementsRes?.data?.elements;
    let pointId;
    if (pointElements) {
      for (let i = 0; i < pointElements.length; i++) {
        if (pointElements[i].type === ElementType.DATUMPOINT) {
          pointId = pointElements[i].id;
          break;
        }
      }
    }
    return pointId;
  }

  getIntersectPoint(linePoint,lineDir,planePoint,planeNormal){
    //判断直线不与平面平行
    if(lineDir.clone().dot(planeNormal) === 0){
      return;
    }
    lineDir.normalize();

    //直线上点在平面的投影
    let linePointProject = this.pointProject(planeNormal,planePoint,linePoint);
    //直线点到直线点投影的向量
    let vectLinePointToProject = linePointProject.clone().sub(linePoint);
    //直线点到直线点投影的距离
    let length = vectLinePointToProject.clone().length();

    vectLinePointToProject.normalize();

    //直线方向与法向的夹角
    let alpha = Math.acos(vectLinePointToProject.clone().dot(lineDir));
    //交点在直线点上的偏移
    let vectOffsetDis = length / Math.cos(alpha);

    //交点
    let intersectPoint = linePoint.clone().add(lineDir.clone().multiplyScalar(vectOffsetDis));
    return intersectPoint;
  }
  //判断是否是最短距离的
  //投影到平面上的三维点
  pointProject(dir,origin,point){
    let pointToOrigin = origin.clone().sub(point);
    let dirNor = dir.clone().normalize();
    let oriNor = pointToOrigin.clone().normalize();
    let alpha = Math.acos(dirNor.clone().dot(oriNor));
    let projectDis = pointToOrigin.length() * Math.cos(alpha);
    let projectPoint = point.clone().add(dirNor.clone().multiplyScalar(projectDis));
    return projectPoint;
  }

  //计算点到平面的距离,根据平面法向有正负之分
  getDisFromPointToPlane(planePoint,planeNormal,point){
    planeNormal.normalize();
    let originToPoint = point.clone().sub(planePoint);
    let dis = planeNormal.clone().dot(originToPoint);
    return dis;
  }

  getPosition(element) {
    let position;
    if (element.type === ElementType.FACE) {
      position = element?.params?.position;
    } else if (element.type === ElementType.DATUMPLANE) {
      position = element?.params?.origin;
    }
    let posVec = new THREE.Vector3(position.x, position.y, position.z)
    return posVec;
  }
  //选取元素重复筛选
  filterRepeatElement(list,ele,singleSelect = false){
    let newList = [];
    let bIsExisted = false;
    //如果是单选，就来判断是否需要进行替换
    if(singleSelect){
      if(list.length > 0 && list[0] && list[0].id === ele.id){
        bIsExisted = true;
      }
    }else{
      list.forEach(tempEle => {
        if(tempEle.id === ele.id){
          bIsExisted = true;
        }else{
          newList.push(tempEle);
        }
      })
    }
    if(!bIsExisted){
      newList.push(ele);
    }
    return newList;
  }
  //设置特征显隐
  async setFeatureVisible(featureId, visible = false) {
    let res = await this.toolQuery.getEntitiesByFeatureId(featureId);
    if (res && res?.data?.entities?.length > 0) {
      let entityId = res?.data?.entities[0].id;
      let status = visible ? 1 : 0;
      await this.command.common.setEntityVisibleIncrement({entityIds: [entityId], status:status });
    }
  }
  async addVariable(name, value, type = ScriptVariableType.Length) {
    await this.command.common.deleteVariableIncrement({variableName: name});
    await this.command.common.createVariableIncrement({
      variableName: name,
      variableValue: value,
      variableType: type,
    })
  }
  getThreeVector3(object){
    let vector3 = new THREE.Vector3();
    if(object.x){
      vector3.x = object.x;
    }else if(object[0]){
      vector3.x = object[0];
    }
    if(object.y){
      vector3.y = object.y;
    }else if(object[1]){
      vector3.y = object[1];
    }
    if(object.z){
      vector3.z = object.z;
    }else if(object[2]){
      vector3.z = object[2];
    }
    return vector3;
  }

  //通过代码获取航向
  getDirCourse(num){
    let dir = new THREE.Vector3();
    if(num === 11){
      dir.x = 1;
    }else if(num === 12){
      dir.x = -1;
    }else if(num === 21){
      dir.y = 1;
    }else if(num === 22){
      dir.y = -1;
    }else if(num === 31){
      dir.z = 1;
    }else if(num === 32){
      dir.z = -1;
    }else{
      dir.x = 1;
    }
    return dir;
  }
  //科学计数法处理
  dealValue(value){
    if(Math.abs(value) < 0.001){
      value = 0;
    }
    return value;
  }
  dealObject(obj){
    if(obj.x){
      obj.x = this.dealValue(obj.x);
    }
    if(obj.y){
      obj.y = this.dealValue(obj.y);
    }
    if(obj.z){
      obj.z = this.dealValue(obj.z);
    }
    return obj;
  }
  async getAddElement(result,type) {
    let element;
    let addElements = result?.data?.modelData?.data?.addElements;
    addElements?.forEach(ele => {
      if (ele.type === type) {
        element = ele;
      }
    })
    return element;
  }
  //添加约束
  async addConstraint(type,params){
    let sketch = this.command.sketch;
    //固定约束
    if(type === CONSTRAINTTYPE.Fix){
      await sketch.addConstraintListIncrement({
        constraintType: "ConstraintType.FixedPoint",
        firstSnapId: params.id,
      })
    }else if(type === CONSTRAINTTYPE.Dis){
      let disPos = new Point();
      if(params.x && params.y){
        disPos = new Point(params.x,params.y);
      }
      await sketch.createDimensionIncrement({
        firstSnapId: params.firstId,
        secondSnapId: params.secondId,
        dimPosition: disPos,
        radiusOrDiameter: 1,
      })
    }else if(type === CONSTRAINTTYPE.Line){
      //共线约束Collineation
      await sketch.addConstraintListIncrement({
        constraintType: "ConstraintType.Collineation",
        firstSnapId: params.firstId,
        secondSnapId: params.secondId,
      })
    }else if(type === CONSTRAINTTYPE.PointOnCurve){
      //点在线上约束
      await sketch.addConstraintListIncrement({
        constraintType: "ConstraintType.PointOnCurve",
        firstSnapId: params.firstId,
        secondSnapId: params.secondId,
        firstSnapType:1,
        secondSnapType:0,
      })
    }
  }
  async getElementByFeatureName(featureNames,no = -1) {
    let elements = await this.query.getElementsByFeatureNames(featureNames);
    let result = [];
    if(elements.data.elements.length > 0)
    {
      result = elements.data.elements;
      if(no !== -1){
        result = [elements.data.elements[no]];
      }
    }
    return result;
  }
  //获取线的哪个端点在平面上
  getStartOrEndOnPlane(guideCurve,planeOrigin,planeNormal){
    let startPoint = this.getThreeVector3(guideCurve.params.curvePoints[0].position);
    let endPoint = this.getThreeVector3(guideCurve.params.curvePoints[1].position);

    let disStart = this.getDisFromPointToPlane(planeOrigin,planeNormal,startPoint);
    let disEnd = this.getDisFromPointToPlane(planeOrigin,planeNormal,endPoint);

    let res = -1;
    if(Math.abs(disStart) < 0.001){
      res = 0;
    }else if(Math.abs(disEnd) < 0.001){
      res = 1;
    }
    return res;
  }
  //通过新增元素获取FeatureId
  getFeatureId(element){
    return element.data.modelData.currentFeature[0].id;
  }
  //对所有二维点进行翻折，1为左右翻折，2为上下翻折，3为原点翻折
  reverseAllPoint2D(pointList,reverseType = 1){
    let newPointList = [];
    for(let n = 0;n < pointList.length;n++){
      let newPoint;
      let curPoint = pointList[n];
      if(reverseType === 1){
        newPoint = new THREE.Vector3(-curPoint.x,curPoint.y);
      }else if(reverseType === 2){
        newPoint = new THREE.Vector3(curPoint.x,-curPoint.y);
      }else if(reverseType === 3){
        newPoint = new THREE.Vector3(-curPoint.x,-curPoint.y);
      }
      newPointList.push(newPoint);
    }
    return newPointList;
  }
  //通过法向和起始终止向量判断起始终止向量的旋转角度
  getRotateAngle(normal,dirS,dirE){
    let rotateAngle = this.acos(dirS.clone().dot(dirE.clone()));
    let dirCross = new THREE.Vector3().crossVectors(dirS,dirE);
    if(dirCross.clone().dot(normal) < 0){
      rotateAngle = -rotateAngle;
    }
    return rotateAngle;
  }
  //通过法向和H方向计算在空间中一点、一向量在该平面上的二维向量
  getSketchPoint(normal,dirH,origin,vector3){
    let datumMatrix = this.getDatumPlaneMatrix(normal,dirH,origin);
    let point2D = vector3.clone().applyMatrix4(datumMatrix.clone().invert());
    return point2D;
  }
  getDatumPlaneMatrix(normal,dirH,origin) {
    let dirV = new THREE.Vector3().crossVectors(normal, dirH);
    //获取三个方向
    let sectionMatrix = new THREE.Matrix4();
    sectionMatrix.makeBasis(dirH, dirV, normal);
    sectionMatrix.setPosition(origin.x, origin.y, origin.z);
    return sectionMatrix;
  }
  compareVector(a, b) {
    let diff = a.clone().sub(b).length();
    return diff;
  }
  //草图内部进行旋转
  rotateInSketch(pointRotate,angle,point){
    let rotateDir = point.clone().sub(pointRotate);
    let targetPointX = rotateDir.x * this.cos(angle) + rotateDir.y * (-this.sin(angle));
    let targetPointY = rotateDir.x * this.sin(angle) + rotateDir.y * this.cos(angle);

    return new THREE.Vector3(targetPointX,targetPointY);
  }
  cos(angle){
    return Math.cos(angle / 180 * Math.PI);
  }
  sin(angle){
    return Math.sin(angle / 180 * Math.PI);
  }
  tan(angle){
    return Math.tan(angle / 180 * Math.PI);
  }
  acos(value){
    return Math.acos(value) * 180 / Math.PI;
  }
}

const InsulationCoverFrameToolCmd = new InsulationCoverFrameToolCommand();
export { InsulationCoverFrameToolCmd }